#include <GLFW/glfw3.h>
#include <glfw_initialization.h>
#include <glfw_monitor.h>
#include <glfw_window.h>
#include <vulkan/vulkan.h>
#include <graphics.h>
#include <glm/gtc/matrix_transform.hpp>

using namespace std;

// 使用 CTRL + K, CTRL + D 来格式化代码。
std::int32_t main(std::int32_t argc, gsl::zstring* argv) {
  cout << "Hello Vulkan!" << endl;

  veng::GlfwInitialization _glfw;

  glm::ivec2 windowSize{1920, 1080};
  glm::vec2 fwindowSize{1920.0f, 1080.0f};
  veng::Window window("Vulkan Engine", windowSize);
  window.TryMoveToMonitor(0);

  veng::Graphics graphics(&window);

  std::array<veng::Vertex, 4> vertices = { 
    veng::Vertex({-0.5f, -0.5f, 0.0f}, {0.0f, 1.0f}),
    veng::Vertex({0.5f, -0.5f, 0.0f}, {1.0f, 1.0f}),
    veng::Vertex({-0.5f, 0.5f, 0.0f}, {0.0f, 0.0f}),
    veng::Vertex({0.5f, 0.5f, 0.0f}, {1.0f, 0.0f})
  };
  veng::BufferHandle buffer = graphics.CreateVertexBuffer(vertices);

  std::array<std::uint32_t, 6> indices = {
    0, 3, 2, 0, 1, 3,
  };
  veng::BufferHandle index_buffer = graphics.CreateIndexBuffer(indices);

  glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
  glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -2.0f));
  glm::mat4 projection = glm::perspective(glm::radians(60.0f), fwindowSize.x / fwindowSize.y, 0.1f, 100.0f);
  graphics.SetViewProjection(view, projection);

  veng::TextureHandle texture = graphics.CreateTexture("assets/paving-stones.jpg");

  while (!window.ShouldClose()) {
    glfwPollEvents();
    if (graphics.BeginFrame()) {
      graphics.SetTexture(texture);
      //graphics.SetModelMatrix(rotation);
      graphics.RenderIndexedBuffer(buffer, index_buffer, indices.size());
      graphics.EndFrame();
    }    
  }

  graphics.DestroyTexture(texture);
  graphics.DestroyBuffer(buffer);
  graphics.DestroyBuffer(buffer);

  return EXIT_SUCCESS;
}
